<template>
  <div>
    <div>
      <div style="border: 1px solid #ccc">
        <Toolbar
          style="border-bottom: 1px solid #ccc"
          :editor="editorRef"
          :default-config="toolbarConfig"
          mode="default"
        />
        <Editor
          v-model="valueHtml"
          style="height: 500px; overflow-y: hidden"
          :default-config="editorConfig"
          mode="default"
          @onCreated="handleCreated"
        />
      </div>
    </div>
  </div>
</template>

<script setup>
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { onBeforeUnmount, ref, shallowRef, defineExpose } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { ElMessage } from 'element-plus'
import { useUserStore } from '../../pinia/modules/user'
import { uploadFile } from '@/api/common'

const path = ref(import.meta.env.VITE_BASE_API)
const userStore = useUserStore()
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()

// 内容 HTML
const valueHtml = ref('<p>默认</p>')
defineExpose({
  valueHtml,
})
// 配置工具栏
const toolbarConfig = { excludeKeys: ['fullScreen'] }

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

const handleCreated = (editor) => {
  editorRef.value = editor // 记录 editor 实例，重要！
}
// 自定义校验链接
function customCheckLinkFn(text, url) {
  if (!url) {
    return
  }
  if (url.indexOf('http') !== 0) {
    return '链接必须以 http/https 开头'
  }
  return true

  // 返回值有三种选择：
  // 1. 返回 true ，说明检查通过，编辑器将正常插入链接
  // 2. 返回一个字符串，说明检查未通过，编辑器会阻止插入。会 alert 出错误信息（即返回的字符串）
  // 3. 返回 undefined（即没有任何返回），说明检查未通过，编辑器会阻止插入。但不会提示任何信息
}
const editorConfig = {
  autoFocus: false,
  // 自定义alert
  customAlert: (s, t) => {
    console.log(
      '%c 🍕 t: ',
      'font-size:20px;background-color: #33A5FF;color:#fff;',
      t
    )
    console.log(
      '%c 🥥 s: ',
      'font-size:20px;background-color: #FCA650;color:#fff;',
      s
    )
    switch (t) {
      case 'success':
        ElMessage.success(s)
        break
      case 'info':
        ElMessage.info(s)
        break
      case 'warning':
        ElMessage.warning(s)
        break
      case 'error':
        ElMessage.error(s)
        break
      default:
        ElMessage.info(s)
        break
    }
  },
  MENU_CONF: {
    placeholder: '请输入内容...',

    // 插入链接
    insertLink: {
      checkLink: customCheckLinkFn, // 也支持 async 函数
    },
    // 更新链接
    editLink: {
      checkLink: customCheckLinkFn, // 也支持 async 函数
    },
    insertImage: {
      onInsertedImage(imageNode) {
        if (imageNode == null) return

        const { src, alt, url, href } = imageNode
        console.log('inserted image', src, alt, url, href)
      },
    },
    uploadImage: {
      // 将 meta 拼接到 url 参数中，默认 false
      metaWithUrl: false,
      server: `http://127.0.0.1:8888/fileUploadAndDownload/upload`,
      fieldName: 'file',
      // 自定义增加 http  header
      headers: {
        xToken: userStore.token,
      },
      customInsert(res, insertFn) {
        // res 即服务端的返回结果
        // 从 res 中找到 url alt href ，然后插图图片
        insertFn(res.data.file.url, res.data.file.name)
      },
      customUpload: async (file, insertFn) => {
        const param = new FormData() // 创建form对象
        param.append('file', file) // 通过append向form对象添加数据
        // file 即选中的文件
        // 自己实现上传，并得到图片 url alt href
        const data = await uploadFile(param)
        const url = data.data.file.url
        const alt = data.data.file.name
        // 最后插入图片
        insertFn(url, alt)
      },
    },
  },
}
</script>
<style lang="scss" scoped>
.w-e-text-container {
  p {
    strong {
      font-weight: bolder !important;
    }
    b {
      font-weight: bold !important;
    }
    i {
      font-style: italic !important;
    }
    em {
      font-style: italic !important;
    }
  }
}
h2 {
  font-weight: bold !important;
  font-size: 1.5em !important;
}
</style>
